package ma.jeetconsulting.pocs.service;

import java.util.ArrayList;
import java.util.List;

import ma.jeetconsulting.pocs.dependencies.profiler.domain.DependencyDao;

import org.apache.maven.model.Dependency;
import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.impl.ClassPathResource;
import org.drools.runtime.StatefulKnowledgeSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DroolsObsoleteDependenciesDetector implements
		ObsoleteDependenciesDetector {

	private static final String GLOBAL_VAR_RESULT = "result";
	private static final String GLOBAl_VAR_DEPENDENCY_DAO = "dependencyDao";
	private static final String RULES_FILE_NAME = "rules.drl";
	private Logger logger = LoggerFactory.getLogger(getClass());
	
	private DependencyDao dependencyDao;

	public List<Dependency> checkForObsoleteDependencies(
			List<Dependency> dependencies) {
		List<Dependency> result = new ArrayList<Dependency>();
		
		StatefulKnowledgeSession session = getStatefullSession(result);
        addDepenciesToSessionAndLunchChecking(dependencies, session);
        session.dispose();
		
		return result;
	}

	private void addDepenciesToSessionAndLunchChecking(List<Dependency> dependencies,
			StatefulKnowledgeSession session) {
		for (Dependency dependency : dependencies) {
			try {
				session.insert(dependency);
			} catch(Exception e) {
				logger.error("An error occur : ", e);
			}
		}
        session.fireAllRules();
	}

	private StatefulKnowledgeSession getStatefullSession(List<Dependency> result) {
		KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        builder.add(new ClassPathResource(RULES_FILE_NAME), ResourceType.DRL);
        
        checkIfThereIsAnyParsingError(builder);
        
        KnowledgeBase base = KnowledgeBaseFactory.newKnowledgeBase();
        base.addKnowledgePackages(builder.getKnowledgePackages());
        StatefulKnowledgeSession session = base.newStatefulKnowledgeSession();
        
        session.setGlobal(GLOBAl_VAR_DEPENDENCY_DAO, dependencyDao);
        session.setGlobal(GLOBAL_VAR_RESULT, result);
        
		return session;
	}

	private void checkIfThereIsAnyParsingError(KnowledgeBuilder builder) {
		KnowledgeBuilderErrors errors = builder.getErrors();
		if (errors.size() > 0) {
            for (KnowledgeBuilderError error : errors) {
                logger.error("Drools error : ", error);
            }
            throw new IllegalArgumentException("Could not parse knowledge.");
        }
	}

	public void setDependecyDao(DependencyDao dependencyDao) {
		this.dependencyDao = dependencyDao;
	}

}
